package com.ruoyi.system.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.hospital.dto.SysAddressDto;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.SysAddressMapper;
import com.ruoyi.system.domain.SysAddress;
import com.ruoyi.system.service.ISysAddressService;

/**
 * 城市字典Service业务层处理
 * 
 * @author wendao
 * @date 2024-12-24
 */
@Service
public class SysAddressServiceImpl implements ISysAddressService 
{
    @Autowired
    private SysAddressMapper sysAddressMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final String REGION_KEY = "sys:region:code:";
    private static final String FULL_ADDRESS_KEY = "sys:region:full_address:";

    private static final String PROVINCE_KEY = "address:province:name2code";
    private static final String CITY_KEY = "address:city:name2code";
    private static final String DISTRICT_KEY = "address:district:name2code";

    /**
     * 查询城市字典
     * 
     * @param id 城市字典主键
     * @return 城市字典
     */
    @Override
    public SysAddress selectSysAddressById(Integer id)
    {
        return sysAddressMapper.selectSysAddressById(id);
    }

    /**
     * 查询城市字典列表
     * 
     * @param sysAddress 城市字典
     * @return 城市字典
     */
    @Override
    public List<SysAddress> selectSysAddressList(SysAddress sysAddress)
    {
        return sysAddressMapper.selectSysAddressList(sysAddress);
    }

    @Override
    public List<SysAddressDto> selectSysAddressByPid(Integer pid) {
        return sysAddressMapper.selectSysAddressByPid(pid);
    }

    /**
     * 新增城市字典
     * 
     * @param sysAddress 城市字典
     * @return 结果
     */
    @Override
    public int insertSysAddress(SysAddress sysAddress)
    {
        redisCache.deleteObject("addressList");
        return sysAddressMapper.insertSysAddress(sysAddress);
    }

    /**
     * 修改城市字典
     * 
     * @param sysAddress 城市字典
     * @return 结果
     */
    @Override
    public int updateSysAddress(SysAddress sysAddress)
    {
        redisCache.deleteObject("addressList");
        return sysAddressMapper.updateSysAddress(sysAddress);
    }

    /**
     * 批量删除城市字典
     * 
     * @param ids 需要删除的城市字典主键
     * @return 结果
     */
    @Override
    public int deleteSysAddressByIds(Integer[] ids)
    {
        return sysAddressMapper.deleteSysAddressByIds(ids);
    }

    /**
     * 删除城市字典信息
     * 
     * @param id 城市字典主键
     * @return 结果
     */
    @Override
    public int deleteSysAddressById(Integer id)
    {
        return sysAddressMapper.deleteSysAddressById(id);
    }

    @Override
    public String getRegionCode(String province, String city, String district) {
        String fullAddress = province + city + district;
        return redisCache.getCacheObject(FULL_ADDRESS_KEY + fullAddress);
    }

    @Override
    //@PostConstruct // 项目启动时自动初始化
    public void initRegionData() {
        SysAddress sysAddress = new SysAddress();
        List<SysAddress> sysAddresses = sysAddressMapper.selectSysAddressList(sysAddress);
        // 构建省市区映射关系
        Map<String, String> provinceMap = new HashMap<>();
        Map<String, String> cityMap = new HashMap<>();
        Map<String, String> districtMap = new HashMap<>();


        for (SysAddress region : sysAddresses) {
            if (region.getLevel() == 0) { // 省
                provinceMap.put(region.getName(), String.valueOf(region.getId()));
            } else if (region.getLevel() == 1) { // 市
                cityMap.put(region.getName(), String.valueOf(region.getId()));
            } else if (region.getLevel() == 2) { // 区
                districtMap.put(region.getName(), String.valueOf(region.getId()));
            }

            // 缓存单个区域编码
            redisCache.setCacheObject(REGION_KEY + String.valueOf(region.getId()), region);
        }

        // 构建完整地址到编码的映射
       /* for (String province : provinceMap.keySet()) {
            for (String city : cityMap.keySet()) {
                for (String district : districtMap.keySet()) {
                    String fullAddress = province + city + district;
                    redisCache.setCacheObject(FULL_ADDRESS_KEY + fullAddress, districtMap.get(district));
                }
            }
        }*/

    }

    @Override
    //@PostConstruct
    public void initAddressCache() {
        System.err.println("城市初始化开始");
        // 清空旧缓存
        clearAddressCache();

        // 缓存省数据
        cacheProvinces();

        // 缓存市数据
        cacheCities();

        // 缓存区县数据
        cacheDistricts();
        System.err.println("城市初始化结束");
    }



    /**
     * 缓存所有省份
     */
    private void cacheProvinces() {

        SysAddress sysAddress = new SysAddress();
        sysAddress.setLevel(0);
        List<SysAddress> provinces = sysAddressMapper.selectSysAddressList(sysAddress);

        Map<String, String> provinceMap = new HashMap<>();
        for (SysAddress province : provinces) {
            provinceMap.put(province.getName(), String.valueOf(province.getId()));
        }
        redisTemplate.opsForHash().putAll(PROVINCE_KEY, provinceMap);
    }

    /**
     * 缓存所有市
     */
    private void cacheCities() {

        SysAddress sysAddress = new SysAddress();
        sysAddress.setLevel(0);
        List<SysAddress> provinces = sysAddressMapper.selectSysAddressList(sysAddress);

        Map<String, String> cityMap  = new HashMap<>();
        for (SysAddress province : provinces) {
            List<SysAddress> cities = sysAddressMapper.selectSysAddressListByPid(province.getId());
            for (SysAddress city : cities) {
                // 使用 "省名:市名" 作为键，避免市名重复
                cityMap.put(province.getName() + ":" + city.getName(), String.valueOf(city.getId()));
            }
        }

        redisTemplate.opsForHash().putAll(CITY_KEY, cityMap);
    }

    /**
     * 缓存所有区县
     */
    private void cacheDistricts() {

        SysAddress sysAddress = new SysAddress();
        sysAddress.setLevel(0);
        List<SysAddress> provinces = sysAddressMapper.selectSysAddressList(sysAddress);

        Map<String, String> districtMap = new HashMap<>();

        for (SysAddress province : provinces) {

            List<SysAddress> cities = sysAddressMapper.selectSysAddressListByPid(province.getId());
            for (SysAddress city : cities) {
                List<SysAddress> districts = sysAddressMapper.selectSysAddressListByPid(city.getId());
                for (SysAddress district : districts) {
                    // 使用 "省名:市名:区名" 作为键，确保唯一性
                    districtMap.put(province.getName() + ":" + city.getName() + ":" + district.getName(), String.valueOf(district.getId()));
                }
            }
        }

        redisTemplate.opsForHash().putAll(DISTRICT_KEY, districtMap);
    }

    /**
     * 通过省名称获取省编码
     */
    public String getProvinceCode(String provinceName) {
        if (StringUtils.isEmpty(provinceName)) {
            return null;
        }
        return (String) redisTemplate.opsForHash().get(PROVINCE_KEY, provinceName);
    }

    /**
     * 通过省和市名称获取市编码
     */
    public String getCityCode(String provinceName, String cityName) {
        if (StringUtils.isEmpty(provinceName) || StringUtils.isEmpty(cityName)) {
            return null;
        }
        return (String) redisTemplate.opsForHash().get(CITY_KEY, provinceName + ":" + cityName);
    }

    /**
     * 通过省、市、区名称获取区编码
     */
    public String getDistrictCode(String provinceName, String cityName, String districtName) {
        if (StringUtils.isEmpty(provinceName) || StringUtils.isEmpty(cityName) || StringUtils.isEmpty(districtName)) {
            return null;
        }
        return (String) redisTemplate.opsForHash().get(DISTRICT_KEY, provinceName + ":" + cityName + ":" + districtName);
    }

    /**
     * 清空地址缓存
     */
    public void clearAddressCache() {
        redisTemplate.delete(PROVINCE_KEY);
        redisTemplate.delete(CITY_KEY);
        redisTemplate.delete(DISTRICT_KEY);
    }

}
